#ifndef ___SIMPLIFY_H__
#define ___SIMPLIFY_H__


#include <OGF/quick_start/common/graph_cell_heap.h>

#include <OGF/cells/common/common.h>
#include <OGF/cells/map/map.h>
#include <OGF/cells/map/map_attributes.h>

#include <OGF/basic/types/counted.h>
#include <OGF/math/attributes/attribute_adapter.h>
#include <OGF/surface/grob/surface.h>

#include <OGF/math/linear_algebra/vector.h>
#include <OGF/math/linear_algebra/matrix.h>
#include <OGF/math/geometry/types.h>

#include <OGF/cells/map/ext_map_editor.h>
#include <OGF/cells/map/geometry.h>
#include <OGF/cells/map/map_cell_heap.h>  

#include <OGF/cells/graph/graph_editor.h>
#include <OGF/cells/graph/graph_attributes.h>
#include <OGF/scene_graph/types/scene_graph.h>
#include <OGF/surface/grob/line.h>


#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <queue>

namespace OGF {


typedef Matrix<double, 4> Matrix4d;


class Simplify
{

public:
	Simplify();
	~Simplify();
	void init(Line*, Surface*);
	void lazy_init(Line*, Surface*);		
	void simplifyMeshSingle();
    	void simplifyMesh ( int vertex_count );
	

private:
	Surface *surface;
	Line *skeleton;

	GraphVertexAttribute<Matrix4d> *vQ;		// Vertex error metrics
	GraphHalfedgeAttribute<double> *edgeError;	// Error associated with collapsing an edge

	
	void initializeVertexError(Graph::Vertex*);
    	void updateLocalVertexErrors(Graph::Vertex*, GraphHalfedgeHeap*);
	Matrix4d getEdgeMetric (Graph::Halfedge*);
	bool isInitialized();
	void collapseEdge(Graph::Halfedge*);
	Point3d getCollapsePoint(Graph::Halfedge*);
	double getCollapseError(Graph::Halfedge*, Point3d);
	double getEdgeSamplingCost(Graph::Halfedge*);
	void simplifyNext(GraphHalfedgeHeap*);


};



}  //namespace
#endif // ___SIMPLIFY_H__
